﻿using System;
using System.Data;
using System.Data.Common;
using DBA.Data.ADO;
using DBA.Data.Hibernate;

namespace DBA.Data
{
    /// <summary>
    /// 处理存储过程的参数
    /// </summary>
    public class ManagerParameter 
    {
        /// <summary>
        /// 数据访问函数库的实例，主要是想操作Command
        /// </summary>
        private DataAccessLibrary dal;

        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="dal">数据访问函数库的实例</param>
        public ManagerParameter(DataAccessLibrary dal)
        {
            this.dal = dal;
        }

        //int：		tinyint、smallint
        //bigint：
        //bool：	bit
        //double：	float、real
        //string：	char、nchar、varchar、nvarchar、uniqueidentifier、smalldatetime、datetime
        //string：	ntext、text

        //decimal：从 -10^38 +1 到 10^38 –1 的固定精度和小数位的数字数据。
        //numeric：功能上等同于 decimal。
        //decimal：	smallmoney、money

        //二进制
        //			binary、varbinary、image

        #region 索引器
        /// <summary>
        /// 对存储过程的参数的一种封装
        /// </summary>
        /// <param name="parameterName">存储过程的参数名称。比如 UserName。注意：参数名称不需要加前缀！</param>
        /// <returns></returns>
        public System.Data.Common.DbParameter this[string parameterName]
        {
            get { return dal.Command.Parameters[this.dal.ParameterPrefix() + parameterName]; }
            set { dal.Command.Parameters[this.dal.ParameterPrefix() + parameterName] = value; }
        }

        /// <summary>
        /// 对存储过程的参数的一种封装
        /// </summary>
        /// <param name="parameterIndex">存储过程的参数名称</param>
        /// <returns></returns>
        public System.Data.Common.DbParameter this[int parameterIndex]
        {
            get { return dal.Command.Parameters[parameterIndex]; }
            set { dal.Command.Parameters[parameterIndex] = value; }
        }
        #endregion

        #region 清除参数
        /// <summary>
        /// 清除Command的存储过程的参数。
        /// </summary>
        public virtual void ClearParameter()
        {
            dal.Command.Parameters.Clear();
        }
        #endregion

        #region 输入型的参数
        /// <summary>
        /// 添加输入型的参数，不用指定参数大小的情况。只支持常用的几个参数类型，如果需要可以扩充。
        /// </summary>
        /// <param name="parameterName">参数名称。比如 UserName。注意：参数名称不需要加前缀！</param>
        /// <param name="parameterValue">参数值</param>
        public virtual void AddNewInParameter(string parameterName, object parameterValue)
        {
            DbParameter par = CommonFactory.CreateParameter(this.dal.ParameterPrefix() + parameterName, this.dal.DatabaseProvider);
            par.Direction = ParameterDirection.Input;
             
            if (parameterValue is Int64)
                par.DbType = DbType.Int64;

            else if (parameterValue is Int32)
                par.DbType = DbType.Int32;

            else if (parameterValue is DateTime)             //日期和时间
                par.DbType = DbType.DateTime;


            else if (parameterValue is Decimal)              //添加金额参数
                par.DbType = DbType.Decimal;

            else if (parameterValue is String)               //ntext、text类型的，不能指定长度
                par.DbType = DbType.String;

            else if (parameterValue is Boolean)
                par.DbType = DbType.Boolean;

            else if (parameterValue is Double)              //小数
                par.DbType = DbType.Single;
            else if (parameterValue is Single)
                par.DbType = DbType.Single;

            else if (parameterValue is Byte[])               //SQL Server 里面的Image类型
                ((System.Data.SqlClient.SqlParameter)par).SqlDbType = SqlDbType.Image;

          
            else if (parameterValue == null)
                par.DbType = DbType.DateTime;
            else
                par.DbType = DbType.String;                 //不在上面的判断范围内的，都定义成string的类型

            par.Value = parameterValue;

            //添加存储过程的参数
            dal.Command.Parameters.Add(par);

        }

        /// <summary>
        /// 添加输入型的参数，nvarchar、carchar、nchar、cahr需要设置参数大小的情况。
        /// </summary>
        /// <param name="parameterName">参数名称。比如 UserName。注意：参数名称不需要加前缀！</param>
        /// <param name="parameterValue">参数值</param>
        /// <param name="parameterSize">参数的大小</param>
        public virtual void AddNewInParameter(string parameterName, object parameterValue, int parameterSize)
        {
            DbParameter parameter = CommonFactory.CreateParameter(this.dal.ParameterPrefix() + parameterName, this.dal.DatabaseProvider);
            parameter.Direction = ParameterDirection.Input;

            parameter.DbType = DbType.String;
            parameter.Size = parameterSize;
            parameter.Value = parameterValue;

            //添加存储过程的参数
            dal.Command.Parameters.Add(parameter);
        }

        public virtual void AddNewInParameter(string parameterName, object parameterValue, DbType dbType, int parameterSize)
        {
            DbParameter parameter = CommonFactory.CreateParameter(this.dal.ParameterPrefix() + parameterName, this.dal.DatabaseProvider);
            parameter.Direction = ParameterDirection.Input;

            parameter.DbType = dbType;
            parameter.Size = parameterSize;
            parameter.Value = parameterValue;           

            //添加存储过程的参数
            dal.Command.Parameters.Add(parameter);
        }

        #endregion

        #region 输出型的参数

        /// <summary>
        /// 添加输出型的参数。只支持常用的几个参数类型，如果需要可以扩充。
        /// </summary>
        /// <param name="parameterName">参数名称。比如 UserName。注意：参数名称不需要加前缀！</param>
        /// <param name="dbType">参数的类型</param>
        public virtual void AddNewOutParameter(string parameterName, DbType dbType)
        {
            DbParameter parameters = CommonFactory.CreateParameter(this.dal.ParameterPrefix() + parameterName, this.dal.DatabaseProvider);
            parameters.Direction = ParameterDirection.InputOutput;
            parameters.DbType = dbType;
            
            //添加存储过程的参数
            dal.Command.Parameters.Add(parameters);
        
        }

        #endregion

        #region 存储过程的参数部分——取参数的返回值

        /// <summary>
        /// 按序号返回参数值，一般在执行完存储过程后使用
        /// </summary>
        /// <param name="ParameterIndex">序号</param>
        /// <returns>返回参数的内容</returns>
        public string GetParameter(int ParameterIndex)
        {
            return dal.Command.Parameters[ParameterIndex].Value.ToString();
        }

        /// <summary>
        /// 按名称返回参数值，一般在执行完存储过程后使用
        /// </summary>
        /// <param name="ParameterName">参数名称。比如 UserName。注意：参数名称不需要加前缀！</param>
        /// <returns>返回参数的内容</returns>
        public string GetParameter(string ParameterName)
        {
            return dal.Command.Parameters[this.dal.ParameterPrefix() + ParameterName].Value.ToString();
        }
        #endregion

        #region 存储过程的参数部分——修改参数值
        /// <summary>
        /// 按序号修改参数值，一般在一次添加多条记录时用。
        /// </summary>
        /// <param name="parameterIndex">序号</param>
        /// <param name="parameterValue">值</param>
        public void SetParameter<T>(int parameterIndex, T parameterValue)
        {
            dal.Command.Parameters[parameterIndex].Value = parameterValue;
        }

        /// <summary>
        /// 按名称修改参数值，一般在一次添加多条记录时用
        /// </summary>
        /// <param name="parameterName">参数名称。比如 UserName。注意：参数名称不需要加前缀！</param>
        /// <param name="parameterValue">值</param>
        public void SetParameter<T>(string parameterName, T parameterValue)
        {
            dal.Command.Parameters[this.dal.ParameterPrefix() + parameterName].Value = parameterValue;
        }
        #endregion

         
    } 
}
